#ifndef _vfx_TEXT_SFX_
#define _vfx_TEXT_SFX_

#include "sfx.h"
#include "ui/ui_sprite.h"
#include "ui/ui_number.h"
#include "math/vec2.h"
#include "math/counter.h"
class Font;
namespace vfx
{

class	SimpleTextSFX : public SFXSet
{
public:
	struct	TextInst
	{
		std::wstring		Text;
		math::Vec2			From;
		math::Vec2			TextSize;
		math::Counter		Life;
		bool				Active;
		COLOR				Color;
	};
	SimpleTextSFX(EffectMan*	pParent, const std::string& Font, float Time, int	MaxCount, bool Floating = true);
	~SimpleTextSFX();
	virtual void			Render(const math::Vec2& Offset, float Scale);
	virtual void			Tick(float dt);
	void					AddText(const std::wstring& Text, const math::Vec2& Pos, COLOR Color = 0xFFFFFFFF);
	void					AddText(const std::string& Text, const math::Vec2& Pos, COLOR Color = 0xFFFFFFFF);
private:
	TextInst*				GetFree();
	int						m_MaxCount;
	int						m_CurrentCount, m_LastFound;
	TextInst*				m_TextA;
	Font*					m_pFont;
	float					m_RiseSpeed;
	bool					m_Floating;
	bool					m_Fading;
	bool					m_Centered;
};

// holder for sprites that only exists for one cycle
class UITextSFX : public SFXSet
{
public:
	struct	TextInst
	{
		ui::UIWidget*		pWidget;
		math::Counter		Life;
		bool				Active;
	};
	UITextSFX(EffectMan*	pParent, const std::string& Image,  const std::string& Font, float Time, int	MaxCount, bool Floating = false, bool AutoResize = false);
	~UITextSFX();
	virtual void			Render(const math::Vec2& Offset, float Scale);
	virtual void			Tick(float dt);
	void					AddText(const std::wstring& Text, const math::Vec2& Pos, const math::Vec2& Size, COLOR Color = 0xFFFFFFFF, bool Centered = false);
	void					AddText(const std::string& Text, const math::Vec2& Pos, const math::Vec2& Size, COLOR Color = 0xFFFFFFFF, bool Centered = false);
private:
	bool					m_AutoResize;
	int						m_MaxCount;
	int						m_CurrentCount;
	TextInst*				m_TextA;
	bool					m_Floating;
};

class NumberFXSet;

class	NumberFXEntry
{
public:			

	enum NUMBERFX_STYLE
	{
		STYLE_SIMPLEFLY,
		STYLE_FLASHANDFLY,
	};

	static const float		FLASH_TIME;

							NumberFXEntry();
	virtual					~NumberFXEntry();
	virtual void			Reset(int Number, int DigitC, const math::Vec2& From, const math::Vec2& To, float Time, bool Fade);
	virtual void			SetupWave(float Speed, float Offset, float Amplitude);
	virtual void			OnCreation() {};
	virtual void			OnArrival();
	bool					IsValid() { return m_CurrentTime > 0; };
	virtual bool			Tick(float dt);
	
	const math::Vec2&		GetPos() const { return m_Pos; };
	int						GetNumber() const { return m_Number; };
	int						GetDigitC() const { return m_DigitC; };
	COLOR					GetColor() const;
	float					GetFraction() const { return 1.0f - (m_CurrentTime / m_MaxTime); };
	float					GetSizeFactor() const { return m_SizeFactor; };
	
	void					SetSFXSet(NumberFXSet*	pSFXSet) { m_pSFXSet = pSFXSet; };
	void					SetColor(COLOR c) { m_Color = c; }
	void					SetMaxTime(float Time) { m_MaxTime = Time; };
	void					SetStyle(NUMBERFX_STYLE Style) { m_Style = Style; };
	
protected:
	NumberFXSet*			m_pSFXSet;
	int						m_Number;
	int						m_DigitC;
	math::Vec2				m_From, m_To, m_Pos;
	float					m_CurrentTime, m_MaxTime;
	float					m_SizeFactor;
	COLOR					m_Color;
	bool					m_Fade;

	// wave pattern
	float					m_Speed, m_Offset, m_Amplitude;
	NUMBERFX_STYLE			m_Style;
};

class	NumberFXSet : public SFXSet
{
public:
								NumberFXSet(EffectMan*	pParent);
	virtual						~NumberFXSet();
	virtual	void				Render(const math::Vec2& Offset, float Scale);
	virtual void				Tick(float dt);
	virtual void				Load(const std::string& File, int MaxNumber);
			void				AddNumber(int Number, const math::Vec2& From, const math::Vec2& To, 
										  COLOR Color = -1, float Time = 1.0f, bool Fade = false, 
										  vfx::NumberFXEntry::NUMBERFX_STYLE Style = NumberFXEntry::STYLE_SIMPLEFLY);
			void				Setup(const math::Vec2& Time, const math::Vec2& Speed, const math::Vec2& Amplitude, bool Fade = false);
protected:
	virtual void				FillNumber(NumberFXEntry*	pNum, int Number, const math::Vec2& From, const math::Vec2& To);
	virtual void				CreateSet(int Max);
	ui::UINumber				m_Number;
	int							m_MaxNumberC;
	int							m_ActiveNumberC;
	int							m_NumberI;
	NumberFXEntry*				m_NumberA;
	float						m_Time;

	math::Vec2					m_MoveTime;
	math::Vec2					m_MoveSpeed;
	math::Vec2					m_MoveAmplitude;
	bool						m_Fade;

	static const int			BUFFER_SIZE	= 1000;
	Graphics::Vertex2D*			m_BufferA;
	int							m_VertexC;
	void						FlushBuffer();

};
};
#endif // _vfx_TEXT_SFX_
